home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_12_04 / suereth / natural.c < prev    next >
C/C++ Source or Header  |  1994-03-09  |  51KB  |  1,479 lines

  1. /*****************************************************/
  2. /* NATURAL.C   Copyright (C) 1993 Russell Suereth    */
  3. /*****************************************************/
  4.  
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <ctype.h>
  9. #include "natural.h"
  10.  
  11. void initialize(void);
  12. void reset_sentence(void);
  13. void get_record(char *);
  14. char *extract_word(void);
  15. int  match_record(char *, int);
  16. char *extract_root(void);
  17. int  check_underlying(void);
  18. int  check_type(char *,int);
  19. void get_aux(void);
  20. int  match_aux(void);
  21. void check_subject(void);
  22. void check_action(void);
  23. void check_place(void);
  24. void check_aux_verb(void);
  25. void check_number(void);
  26. void make_response(void);
  27. void make_answer(int);
  28. void get_verb(char, char, char);
  29. int  match_verb(char, char, char);
  30. int  ask_meaning(void);
  31. void check_time(void);
  32. void derive_aux_meaning(void);
  33. void derive_time_meaning(void);
  34. int  check_agreement(void);
  35. void check_time(void);
  36. void agreement_error(int);
  37. void aux_meaning_response(void);
  38.  
  39. FILE *infile;
  40. char dic_record[80];
  41. int  sentence;
  42. int  word_ct;
  43. char word_array[10][25];
  44. char root_array[10][25];
  45. char prime_types[10][11];
  46. char phrases[10][11];
  47. char type_array[10][5][11];
  48. char subjects[20][25];
  49. char actions[20][25];
  50. char places[20][31];
  51. char response[200];
  52. unsigned char verb_tense[5];
  53. unsigned char verb_number[5];
  54. unsigned char verb_usage;
  55. unsigned char aux_tense[5];
  56. unsigned char aux_number[5];
  57. unsigned char aux_usage;
  58. unsigned char subject_number;
  59. unsigned char tenses[20];
  60. unsigned char numbers[20];
  61. unsigned char usages[20];
  62. unsigned char subjects_type[20];
  63. unsigned char aux_meaning[20][5];
  64. char auxiliaries[20][25];
  65. char times[20][31];
  66. unsigned char time_meaning[20];
  67.  
  68.  
  69.  
  70. void main()
  71. {
  72.     char  *cur_word;
  73.     char  in_sentence[80];
  74.  
  75.     initialize();
  76.     if ((infile = fopen("diction", "r+")) == NULL) {
  77.         printf ("\nError opening dictionary\n");
  78.         exit(0);
  79.     }
  80.     printf("\nSentence: ");
  81.  
  82.     while(gets(in_sentence)) {
  83.         if (in_sentence[0] == '\0') break;
  84.         reset_sentence();
  85.  
  86.         cur_word = strtok(in_sentence, " ");
  87.         while(cur_word != NULL) {
  88.             get_record(cur_word);
  89.             cur_word = strtok(NULL, " ");
  90.             if (++word_ct > 9) break;
  91.         }
  92.  
  93.         if (check_underlying() == 0) {
  94.             check_subject();
  95.             check_action();
  96.             check_place();
  97.             check_aux_verb();
  98.             check_number();
  99.  
  100.             check_time();
  101.             derive_time_meaning();
  102.             derive_aux_meaning();
  103.  
  104.         }
  105.  
  106.         make_response();
  107.  
  108.         printf("Response: %s\n\nSentence: ", response);
  109.  
  110.         if (++sentence > 19) break;
  111.     }   /*  end while  */
  112.  
  113.     fclose(infile);
  114.     return;
  115. }
  116.  
  117. /*****************************************************/
  118. /* Initialize variables.                             */
  119. /*****************************************************/
  120. void initialize()
  121. {
  122.     sentence              = 0;
  123.     memset(subjects,      '\0', 500);
  124.     memset(actions,       '\0', 500);
  125.     memset(places,        '\0', 620);
  126.     memset(tenses,        '\0',  20);
  127.     memset(numbers,       '\0',  20);
  128.     memset(usages,        '\0',  20);
  129.     memset(subjects_type, '\0',  20);
  130.     memset(aux_meaning,   '\0', 100);
  131.     memset(auxiliaries,   '\0', 500);
  132.     memset(time_meaning,  '\0',  20);
  133.     memset(times,         '\0', 620);
  134.  
  135.     return;
  136. }
  137.  
  138. /*****************************************************/
  139. /* These variables are initialized for each new      */
  140. /* input sentence.                                   */
  141. /*****************************************************/
  142. void reset_sentence()
  143. {
  144.     word_ct                      = 0;
  145.     memset(word_array,    '\0', 250);
  146.     memset(root_array,    '\0', 250);
  147.     memset(prime_types,   '\0', 110);
  148.     memset(phrases,       '\0', 110);
  149.     memset(type_array,    '\0', 550);
  150.     response[0]               = '\0';
  151.     return;
  152. }
  153.  
  154. /*****************************************************/
  155. /* Get all the records from the dictionary. If the   */
  156. /* passed word is not in the dictionary, then the    */
  157. /* word could be a name.                             */
  158. /*****************************************************/
  159. void get_record(char *pass_word)
  160. {
  161.     int types = 0;
  162.     rewind (infile);
  163.     fgets(dic_record, 80, infile);
  164.     while (! feof(infile)) {
  165.         if (match_record(pass_word, types) == 0)
  166.             types++;
  167.         fgets(dic_record, 80, infile);
  168.     }
  169.     if (types == 0) {
  170.         if (isupper( (int) pass_word[0]))
  171.             strcpy(type_array[word_ct][types], "NAME");
  172.         else
  173.             strcpy(type_array[word_ct][types],
  174.                    "NOTFOUND");
  175.     }
  176.     strcpy(word_array[word_ct], pass_word);
  177.     return;
  178. }
  179.  
  180. /*****************************************************/
  181. /* Compare the passed word with the word in the      */
  182. /* current dictionary record. If they are the same,  */
  183. /* then extract the type (NOUN, VERB, etc.). If the  */
  184. /* type is PRON, then extract pronoun information.   */
  185. /* If the type is VERB, then extract verb            */
  186. /* information.                                      */
  187. /*****************************************************/
  188. int  match_record(char *pass_word, int types)
  189. {
  190.     int i, j;
  191.     char *root;
  192.     char *dic_word;
  193.     dic_word = extract_word();
  194.     /* Check if passed word equals dictionary word   */
  195.     if (strcmpi(pass_word, dic_word) != 0) return(1);
  196.  
  197.     /* Word found, get the type                      */
  198.     for (i=24,j=0; i<28; i++) {
  199.        if (isspace(dic_record[i])) break;
  200.        type_array[word_ct][types][j++] = dic_record[i];
  201.     }
  202.     /* Trim the type                                 */
  203.     type_array[word_ct][types][j] = '\0';
  204.  
  205.     if (strcmp(type_array[word_ct][types],
  206.                 "PRON") == 0)
  207.         subject_number = dic_record[41];
  208.  
  209.     if (strcmp(type_array[word_ct][types],
  210.                 "VERB") == 0) {
  211.         root = extract_root();
  212.         strcpy(root_array[word_ct], root);
  213.         verb_usage  = dic_record[29];
  214.         for (i=30,j=0; i<34; i++,j++) {
  215.            if (isspace(dic_record[i])) break;
  216.            verb_tense[j] = dic_record[i];
  217.         }
  218.         verb_tense[j] = '\0';
  219.         for (i=41,j=0; i<43; i++,j++) {
  220.            if (isspace(dic_record[i])) break;
  221.            verb_number[j] = dic_record[i];
  222.         }
  223.         verb_number[j] = '\0';
  224.     }
  225.  
  226.     return(0);
  227. }
  228.  
  229. /*****************************************************/
  230. /* Extract the word from the dictionary. The word is */
  231. /* 24 characters in length and starts in column 1.   */
  232. /*****************************************************/
  233. char *extract_word()
  234. {
  235.     int i;
  236.     char dic_word[25];
  237.     strncpy(dic_word, dic_record, 24);
  238.     for (i=23; i>=0; i--) {
  239.         if (isspace(dic_word[i])) {
  240.             dic_word[i] = '\0';
  241.             continue;
  242.         }
  243.         break;
  244.     }
  245.     return(dic_word);
  246. }
  247.  
  248. /*****************************************************/
  249. /* Extract the root from the dictionary. It          */
  250. /* identifies a group of similar words (the root for */
  251. /* run, ran, runs and running is run). It is 14      */
  252. /* characters in length and starts in column 47.     */
  253. /*****************************************************/
  254. char *extract_root()
  255. {
  256.     int i, j;
  257.     char root[15];
  258.     for (i=46,j=0; i<60; i++) {
  259.         if (isspace(dic_record[i])) break;
  260.         root[j++] = dic_record[i];
  261.     }
  262.     /* Trim the root                                 */
  263.     root[j] = '\0';
  264.     return(root);
  265. }
  266.  
  267. /*****************************************************/
  268. /* Determine if the input sentence contains a known, */
  269. /* underlying structure. If it does, then assign the */
  270. /* correct types and phrases for the words.          */
  271. /*****************************************************/
  272. int  check_underlying()
  273. {
  274.     int i = 0;
  275.  
  276.     /* Structure PRON-AUX-VERB-PREP-DET-NOUN         */
  277.     if ( (check_type("PRON",   i) == 0) &&
  278.          (check_type("AUX